package com.ruoyi.web.core.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 商户私钥缓存：按 orgId + appId 缓存私钥内容（PEM）
 */
@Component
public class MerchantKeyCache {
    private static final Logger log = LoggerFactory.getLogger(MerchantKeyCache.class);

    private final Map<String, String> cache = new ConcurrentHashMap<>();

    /**
     * 获取或拉取私钥
     * @param orgId 组织ID
     * @param appId 微信AppID
     * @param keyUrl 对象存储中的私钥URL（pem文件地址）
     * @return 私钥PEM内容
     */
    public String getOrFetchPrivateKey(String orgId, String appId, String keyUrl) {
        String key = orgId + ":" + appId;
        String pk = cache.get(key);
        if (pk != null && !pk.isEmpty()) {
            return pk;
        }
        // 拉取并缓存
        String fetched = fetchPemFromUrl(keyUrl);
        if (fetched == null || fetched.isEmpty()) {
            throw new RuntimeException("无法从存储桶URL获取私钥内容: " + keyUrl);
        }
        cache.put(key, fetched);
        return fetched;
    }

    private String fetchPemFromUrl(String keyUrl) {
        HttpURLConnection conn = null;
        try {
            URL url = new URL(keyUrl);
            conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setConnectTimeout(5000);
            conn.setReadTimeout(5000);
            int code = conn.getResponseCode();
            if (code != 200) {
                log.error("下载私钥失败，HTTP状态码：{}，URL：{}", code, keyUrl);
                return null;
            }
            try (BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8))) {
                StringBuilder sb = new StringBuilder();
                String line;
                while ((line = reader.readLine()) != null) {
                    sb.append(line).append("\n");
                }
                return sb.toString();
            }
        } catch (Exception e) {
            log.error("拉取私钥异常：{}", e.getMessage(), e);
            return null;
        } finally {
            if (conn != null) {
                conn.disconnect();
            }
        }
    }
}